package com.feimt.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feimt.dto.DishDto;
import com.feimt.mapper.DishMapper;
import com.feimt.pojo.Category;
import com.feimt.pojo.Dish;
import com.feimt.pojo.DishFlavor;
import com.feimt.result.R;
import com.feimt.service.CategoryService;
import com.feimt.service.DishFlavorService;
import com.feimt.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author 宋孟林
 * @description
 */
@RestController
@Slf4j
@RequestMapping("/dish")
public class DishController {
    private DishService dishService;
    private DishFlavorService dishFlavorService;
    private CategoryService categoryService;

    @Autowired
    public DishController(DishService dishService, DishFlavorService dishFlavorService, CategoryService categoryService) {
        this.dishService = dishService;
        this.dishFlavorService = dishFlavorService;
        this.categoryService = categoryService;
    }
    /**
     * 新增菜品控制器，由于我们前端要求的菜品展示是有菜品表和风味表来展示的，设计到两个表和数据传输对象，
     * 我们要使用自定义的新增方法
     * @param dishDTO 保存参数，数据传输对象
     * @return 返回是否新增成功
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDTO){
        log.info("dishDTO is: {}" , dishDTO.toString());
        dishService.saveDishWithFlavor(dishDTO);
        return R.success("新增菜品成功");
    }
    /**
     * 分页查询菜品信息及其对应的分类名称。
     * 此方法根据分页参数和可选的菜品名称过滤条件，查询菜品的分页数据。
     * 查询结果不仅包含菜品的基本信息，还会附加每个菜品对应的分类名称。
     * @param page 当前页码（从 1 开始）
     * @param pageSize 每页记录数
     * @param name （可选）菜品名称，用于模糊查询
     * @return 返回包含分页菜品信息及分类名称的响应结果 {@link R}，其中包含分页对象 {@link IPage} 包装的菜品数据 {@link DishDto}
     */
    @GetMapping("/page")
    public R<IPage<DishDto>> page(Integer page, Integer pageSize, String name){
        log.info("page:{},pageSize:{},name:{}", page, pageSize, name);
        IPage<Dish> dishPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(name != null, Dish::getName, name);
        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        dishService.page(dishPage, wrapper);
        IPage<DishDto> dishDtoPage = new Page<>(page, pageSize);
        BeanUtils.copyProperties(dishPage, dishDtoPage,"records");
        List<Dish> records = dishPage.getRecords();
        List<DishDto> dishDtoList = records.stream().map(item -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return dishDto;
        }).collect(Collectors.toList());
        dishDtoPage.setRecords(dishDtoList);
        return R.success(dishDtoPage);
    }

    /**
     * 数据回显，我们修改菜品信息的时候，需要先把此id的菜品信息回显到前端显示
     * @param id 根据id来查询
     * @return dto数据
     */
    @GetMapping("/{id}")
    public R<DishDto> getData(@PathVariable Long id){
        DishDto dishDTO = dishService.getByIdWithFlavor(id);
        return R.success(dishDTO);
    }

    /**
     * 更改菜品信息完毕后使用自定义的更新方法返回dishDto对象
     * @param dishDto json请求
     * @return 返回是否成功
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        log.info("dishDto的值为:{}", dishDto.toString());
        boolean b = dishService.updateWithFlavor(dishDto);
        return b ? R.success("修改成功") : R.error("修改失败");
    }

    /**
     * 删除菜品功能实现，根据传入的ids集合来使用dishService的批量删除功能来删除菜品
     * @param ids 传入需要删除的id集合，如果参数是集合一定要有@RequestParam注解
     * @return 返回是否成功
     */
    @DeleteMapping
    public R<String> deleteBatch(@RequestParam List<Long> ids){
        log.info("删除菜品，ids为：{}", ids);
        boolean b = dishService.customRemoveByIds(ids);
        return b ? R.success("删除成功") : R.error("删除失败");
    }

    /**
     * 修改是否停售的状态信息
     * @param status 传入应该设计的状态
     * @param ids 传入需要更改的id集合
     * @return 返回是否修改成功
     */
    @PostMapping("/status/{status}")
    public R<String> updateBatchStatus(@PathVariable Integer status , @RequestParam List<Long> ids){
        LambdaUpdateWrapper<Dish> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(Dish::getId, ids).set(Dish::getStatus, status);
        boolean b = dishService.update(wrapper);
        return b ? R.success("修改成功") : R.error("修改失败");
    }

    /**
     * 展示菜品，当种类id不为空时根据种类id同时一定要是在售状态才可以被查询到
     * @param dish 传入的是菜品对象
     * @return 返回查询的集合
     */
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId()).eq(Dish::getStatus, 1);
        wrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
        List<Dish> list = dishService.list(wrapper);
        List<DishDto> dishDtoList  = list.stream().map((item) ->{
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            Long id = item.getId();
            LambdaQueryWrapper<DishFlavor> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(DishFlavor::getDishId, id);
            List<DishFlavor> list1 = dishFlavorService.list(wrapper1);
            dishDto.setFlavors(list1);
            return dishDto;
        }).collect(Collectors.toList());
        return R.success(dishDtoList);
    }

//    @Resource
//    DishMapper dishMapper;
//    @GetMapping("/alter")
//    public R<?> alterDishCode(){
//        List<Dish> dishes = dishMapper.selectList(null);
//        for (Dish dish : dishes) {
//            String dishCode = dish.getCode();
//            if (dishCode != null){
//                String uuid = UUID.randomUUID().toString();
//                dish.setCode(uuid);
//                LambdaUpdateWrapper<Dish> wrapper = new LambdaUpdateWrapper<>();
//                wrapper.eq(Dish::getId, dish.getId()).set(Dish::getCode, dish.getCode());
//                dishMapper.update(null, wrapper);
//            }
//        }
//        return R.success("成功");
//    }
}
